package com.zhangqiang.git.cloud.oauth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @ClassName: OAuth2AuthorizationServer
 * @Description: 认证服务
 * @author: zhangqiang
 * @date: 2021/3/1
 * 
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
	@Autowired
	public PasswordEncoder passwordEncoder;

	@Autowired
	private TokenStore redisTokenStore;

	@Autowired
	public UserDetailsService userDetailsService;

	@Autowired
	private AuthenticationManager authenticationManager;

	/**
	 * 用来配置令牌端点(Token Endpoint)的安全约束
	 * @param security
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerSecurityConfigurer security)
			throws Exception {
		// code授权添加
		security.tokenKeyAccess("permitAll()")
				.checkTokenAccess("isAuthenticated()")
				.allowFormAuthenticationForClients();
	}

	/**
	 * 引入自定义userDetail
	 *
	 * @param endpoints
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.authenticationManager(authenticationManager)
				.userDetailsService(userDetailsService)
				.tokenStore(redisTokenStore);
	}

	/**
	 * 用来配置客户端详情服务（ClientDetailsService），
	 * 客户端详情信息在这里进行初始化，
	 * 你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息
	 * @param clients
	 * @throws Exception
	 */
	@Override
	public void configure(ClientDetailsServiceConfigurer clients)
			throws Exception {

		// 认证客户端目前为固定值,后续可以做成配置文件或者数据库获取方式（注意：可以配置多个客户端）
		// client = oauth2_id_20210222
		// secret = oauth2_secret_20210222
		// https://open.bot.tmall.com/oauth/callback  https://localhost:8080
		clients.inMemory().withClient("oauth2_id_20210222")
				.secret(passwordEncoder.encode("oauth2_secret_20210222"))
				.scopes("all")
				.authorizedGrantTypes(
						"authorization_code",
						"client_credentials",
						"password",
						"refresh_token"
				)
//				.authorities("READ_ONLY_CLIENT").scopes("read_user_info")
				.resourceIds("oauth2-resource")
				//https://localhost:8080 https://open.bot.tmall.com/oauth/callback
				.redirectUris("https://open.bot.tmall.com/oauth/callback")
				.accessTokenValiditySeconds(5000)
				.refreshTokenValiditySeconds(50000)
				//.and()可以设置多个客户端
				;
	}

}